package ar.uba.is2.tr.impl;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import ar.uba.is2.common.mensaje.DatoSensado;
import ar.uba.is2.common.mensaje.Mensaje;
import ar.uba.is2.common.mensaje.TipoMensaje;
import ar.uba.is2.common.mensaje.contenido.ContenidoDatosSensados;
import ar.uba.is2.tr.ComunicadorECDao;
import ar.uba.is2.tr.DatoSensadoBo;
import ar.uba.is2.tr.conf.Contexto;

/**
 * Encargado de buscar los datos que no hayan sido enviados a la EC y enviarlos.
 * Para esto puede ser necesario enviar mas de un paquete.
 */
public class MensajeriaEcImpl implements Runnable {

	private static final int TIEMPO_ENVIO_MENSAJE_A_EC = Integer.parseInt(Contexto.instance.get("tr.mensajeria.msg.sending.time"));

	private Logger log = Logger.getLogger(MensajeriaEcImpl.class);
	private DatoSensadoBo datoSensadoBo;
	private ComunicadorECDao comunicadorECDao;
	private Date ultimaFechaDeEnvio;
	private static int nroMensaje = 0;

	public MensajeriaEcImpl() {
		datoSensadoBo = new DatoSensadoBoImpl();
		comunicadorECDao = new ComunicadorECDaoImpl();
		ultimaFechaDeEnvio = new Date();
	}


	public void run() {
		log.debug("Empieza a buscar datos para enviar a la EC");
		while (true) {
			enviarMensajeYEsperar();
		}

	}

	private synchronized void enviarMensajeYEsperar() {
		try {
			enviarMensaje();
			wait(TIEMPO_ENVIO_MENSAJE_A_EC);
		} catch (InterruptedException e) {
			log.debug("no pudo dormir un minuto", e);
		}
	}

	/**
	 * 
	 * @return
	 */
	private void enviarMensaje() {

		List<DatoSensado> datosSensado = datoSensadoBo.buscarTodosMayores(ultimaFechaDeEnvio);
		
		ultimaFechaDeEnvio = new Date();

		if (datosSensado == null || datosSensado.isEmpty()) {
			log.info("No encuentra datos");
			return;
		}

		log.info(String.format("Encuentra %s datos", datosSensado.size()));

		Mensaje mensaje = armarMensaje(datosSensado);
		Contexto.instance.getModuloComunicacion().enviarMensaje(mensaje);
	}


	private Mensaje armarMensaje(List<DatoSensado> datosSensado) {
		
		Mensaje mensaje = new Mensaje();
		mensaje.setNumeroMensaje(nroMensaje++);
		mensaje.setTipoMensaje(TipoMensaje.DATOS_SENSADOS);
		mensaje.setDestino(Contexto.instance.getComponenteEstacionCentral());
		mensaje.setOrigen(Contexto.instance.getComponenteTerminalRemotaLocal());
		mensaje.setCantidadPartes(1);
		mensaje.setParte(0);
		mensaje.setFechaCreacion(new Date());
		
		ContenidoDatosSensados contenido = new ContenidoDatosSensados();
		
		for (DatoSensado datoSensado : datosSensado) {
			contenido.addDatoSensado(datoSensado);
		}
		
		mensaje.setContenido(contenido);

		return mensaje;
		
	}

	public DatoSensadoBo getDatoSensadoBo() {
		return datoSensadoBo;
	}

	public void setDatoSensadoBo(DatoSensadoBo datoSensadoBo) {
		this.datoSensadoBo = datoSensadoBo;
	}

	public ComunicadorECDao getComunicadorECDao() {
		return comunicadorECDao;
	}

	public void setComunicadorECDao(ComunicadorECDao comunicadorECDao) {
		this.comunicadorECDao = comunicadorECDao;
	}

}
